package gdingtalk

import (
	"encoding/json"
	"gitee.com/zjlsliupei/ghelp"
)

type User struct {
	// 同步人员时，最大同步人数，超过后会不处理
	syncMaxUserCount int
}

func NewUser(syncMaxUserCount int) User {
	return User{
		syncMaxUserCount: syncMaxUserCount,
	}
}

// GetUsersByDeptIds 获取该部门下所有子部门，算法采用递归调用，注意部门嵌套深度
func (__ *User) GetUsersByDeptIds(corpId string, deptIds []int64) []map[string]interface{} {
	var users []map[string]interface{}
	for _, v := range deptIds {
		_users := __.GetUsersByDeptId(corpId, v, 0, 100)
		if len(_users) > 0 {
			users = append(users, _users...)
			if __.overUserCount(users) {
				return __.trimUser(users)
			}
		}
	}
	return users
}

// GetUsersByDeptId 获取部门下完整用户信息
// deptId 部门id
// cousor 分页码，从0开始
// size 分页大小，最大100，如果该部门上下用户数超过100，函数会自动递归调用合并后一起返回
func (__ *User) GetUsersByDeptId(corpId string, deptId int64, cursor int64, size int64) []map[string]interface{} {
	var users []map[string]interface{}
	res := Post().
		AutoAccessToken(corpId).
		SetPath("/topapi/v2/user/list").
		AddBodyParam("dept_id", deptId).
		AddBodyParam("cursor", cursor).
		AddBodyParam("size", size).
		Do()
	if !res.IsSuccess() {
		return users
	}
	if len(res.GetBody("result.list").Array()) > 0 {
		var u []map[string]interface{}
		if err := json.Unmarshal([]byte(res.GetBody("result.list").Raw), &u); err == nil {
			users = u
		}
	}
	if !res.GetBody("result.has_more").Bool() {
		return users
	}
	return append(users, __.GetUsersByDeptId(corpId, deptId, cursor+1, size)...)
}

// GetDetail 查询用户详情
func (__ *User) GetDetail(corpId, userId string) map[string]interface{} {
	res := Post().
		AutoAccessToken(corpId).
		SetPath("/topapi/v2/user/get").
		AddBodyParam("userid", userId).
		Do()
	if !res.IsSuccess() {
		return nil
	}
	return res.GetBody("result").Value().(map[string]interface{})
}

// GetScopedAllUsers 获取企业下所有用户信息（已经授权的用户）
func (__ *User) GetScopedAllUsers(corpId string) []map[string]interface{} {
	var users []map[string]interface{}
	auth := NewAuth()
	res := auth.GetAuthScopes(corpId)
	if !res.IsSuccess() {
		return users
	}

	// isv模式下，优化解析开通授权人，通常情况下开通人会第一时间点进去，如果不优先同步他的信息，会导致查不到该用户数据
	if gOption.Type == "isv" {
		_isv, errisv := NewIsv(gOption.DingParams)
		if errisv == nil {
			res2 := _isv.GetAuthInfo(corpId)
			if res2.IsSuccess() {
				openUserId := res2.GetBody("authUserInfo.userId").String()
				// 如果开通人不在授权范围内，detail会报错，那么不处理
				if _u := __.GetDetail(corpId, openUserId); _u != nil {
					users = append(users, _u)
				}
			}
		}
	}

	// 解析授权用户
	if len(res.GetBody("auth_org_scopes.authed_user").Array()) > 0 {
		for _, v := range res.GetBody("auth_org_scopes.authed_user").Array() {
			if _u := __.GetDetail(corpId, v.String()); _u != nil {
				users = append(users, _u)
			}
		}
	}
	if __.overUserCount(users) {
		return __.trimUser(users)
	}
	// 解析授权部门
	if len(res.GetBody("auth_org_scopes.authed_dept").Array()) > 0 {
		dept := NewDepartment()
		var deptIds []int64
		for _, v := range res.GetBody("auth_org_scopes.authed_dept").Array() {
			deptIds = append(deptIds, v.Int())
			_depts := dept.GetAllSubDept(corpId, v.Int())
			if len(_depts) > 0 {
				for _, v2 := range _depts {
					if deptId, ok := v2["dept_id"]; ok {
						deptIds = append(deptIds, int64(deptId.(float64)))
					}
				}
			}
		}
		if len(deptIds) > 0 {
			users = append(users, __.GetUsersByDeptIds(corpId, deptIds)...)
		}
	}
	return __.trimUser(users)
}

func (__ *User) overUserCount(users []map[string]interface{}) bool {
	if len(users) >= __.syncMaxUserCount {
		return true
	} else {
		return false
	}
}

func (__ *User) trimUser(users []map[string]interface{}) []map[string]interface{} {
	// users 去重
	var _users []map[string]interface{}
	var userIds []string
	for _, v := range users {
		if userId, ok := v["userid"]; ok {
			if !ghelp.InArray(userId.(string), userIds) {
				userIds = append(userIds, userId.(string))
				_users = append(_users, v)
			}
		}
	}
	if len(_users) <= __.syncMaxUserCount {
		return _users
	}
	return _users[0:__.syncMaxUserCount]
}
